home *** CD-ROM | disk | FTP | other *** search
- /* vim: set sw=2 sts=2 ts=8 et syntax=javascript: */
-
- // Aviary authentication component. Implements the aviaryIAuth interface.
- // This component also sets aviary-hide-tbitem="true" on windows in FF < 3.1.
-
- var gAviaryAuth = {
- kContractID: "@aviary.com/aviary-auth;1",
- kServiceName: "Aviary Auth Service",
- kClassID: Components.ID("{7AC8EEB4-8567-4675-B50F-441ED78DCD2A}"),
-
- kDefaultToolsList: "20,Falcon,3,Peacock,1,Phoenix,4,Raven,2,Toucan,6,Myna",
- kLoginCookieName: "marketplaceauth",
-
- mIsLoggedIn: false, // cached value (last known state).
- mToolsList: null, // cached value (last known state).
- mIsFirstWindow: true,
- mCanCaptureFlash: false,
- mAviaryServerHost: "aviary.com", // Reset from pref at domwindowopened.
- mObsSvc: null,
- mPearlUtilRequest: null,
-
- kLoginStatusTimerInterval: 350, // 0.35 seconds
- mLoginStatusTimer: null,
-
- // nsISupports implementation.
- QueryInterface: function (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsISupports) &&
- !aIID.equals(Components.interfaces.nsIClassInfo) &&
- !aIID.equals(Components.interfaces.nsIFactory) &&
- !aIID.equals(Components.interfaces.nsIObserver) &&
- !aIID.equals(Components.interfaces.aviaryIAuth))
- {
- dump("gAviaryAuth bad QI: " + aIID + "\n");
- throw Components.results.NS_ERROR_NO_INTERFACE;
- }
-
- return this;
- },
-
- // nsIClassInfo implementation.
- getInterfaces: function(aCount)
- {
- var iList = [ Components.interfaces.nsISupports,
- Components.interfaces.nsIClassInfo,
- Components.interfaces.nsIFactory,
- Components.interfaces.nsIObserver,
- Components.interfaces.aviaryIAuth ];
- aCount.value = iList.length;
- return iList;
- },
-
- getHelperForLanguage: function (aLanguage)
- {
- return null;
- },
-
- contractID: this.kContractID,
- classDescription: this.kServiceName,
- classID: this.kClassID,
- implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
- flags: Components.interfaces.nsIClassInfo.DOM_OBJECT,
-
- // nsIFactory implementation.
- createInstance: function (aOuter, aIID)
- {
- if (null != aOuter)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
-
- return this.QueryInterface(aIID);
- },
-
- lockFactory: function (aDoLock) {},
-
- // nsIObserver implementation.
- observe: function(aSubject, aTopic, aData)
- {
- if ("app-startup" == aTopic)
- {
- this.mToolsList = this.kDefaultToolsList;
-
- this.mObsSvc = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- this.mObsSvc.addObserver(this, "domwindowopened", false);
- }
- else if ("domwindowopened" == aTopic)
- {
- if (this.mIsFirstWindow)
- {
- this.mIsFirstWindow = false;
- this.mObsSvc.addObserver(this, "aviary:loginstatus", false);
- this.mObsSvc.addObserver(this, "aviary:toolsavailable", false);
- this.mObsSvc.addObserver(this, "cookie-changed", false);
-
- try
- {
- var prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- var serverPrefix = prefSvc.getCharPref("aviary.serverPrefix");
- var ioSvc = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService);
- var serverURI = ioSvc.newURI(serverPrefix, null, null);
- var host = this.getHostFromURI(serverURI);
- if (host)
- this.mAviaryServerHost = host;
- } catch (e) {}
-
- // In Firefox 3.5, XMLHttpRequest fails if we use it right away.
- // Therefore, kick off our timer to do a "gettoollist" call.
- this.startLoginStatusTimer();
-
- // Set mCanCaptureFlash based on Firefox version (>= 3.1).
- var v = Components.classes["@mozilla.org/xre/app-info;1"]
- .getService(Components.interfaces.nsIXULAppInfo).version;
- var ffVersion = parseFloat(v);
- this.mCanCaptureFlash = (ffVersion >= 3.1);
- }
-
- // In Firefox versions prior to 3.1, we cannot capture Flash content in
- // Aviary tool windows. Arrange to be called after each XUL window loads
- // so we can set aviary-hide-tbitem="true" to hide the capture toolbar
- // item.
- if (!this.mCanCaptureFlash && aSubject)
- {
- var _this = this;
- aSubject.addEventListener("load",
- function(aEvent) {
- aEvent.currentTarget.removeEventListener("load",
- arguments.callee, false);
- _this.checkForToolsWindow(aEvent.currentTarget);
- }, false);
- }
- }
- else if ("aviary:loginstatus" == aTopic)
- {
- this.mIsLoggedIn = ("true" == aData);
- this.cancelLoginStatusTimer();
- // dump("cached mIsLoggedIn is now: " + this.mIsLoggedIn + "\n");
- }
- else if ("aviary:toolsavailable" == aTopic)
- {
- this.mToolsList = aData;
- // dump("cached tools is now: " + this.mToolsList + "\n");
- }
- else if ("cookie-changed" == aTopic)
- {
- if (aData == "cleared") // all cookies removed
- {
- // dump("all cookies cleared\n");
- this.startLoginStatusTimer();
- }
- else if (aSubject instanceof Components.interfaces.nsICookie)
- {
- if (this.kLoginCookieName == aSubject.name)
- {
- // Check cookie host/domain against mAviaryServerHost (case
- // insensitive match; remove leading and trailing '.' if present).
- var host = aSubject.host.toLowerCase();
- if ((host.length > 0) && ('.' == host.charAt(0)))
- host = host.substr(1);
- if ((host.length > 0) && ('.' == host.substr(-1)))
- host = host.substr(0, host.length - 1);
- if (this.mAviaryServerHost == host)
- {
- // dump("cookie " + aData + " - " + aSubject.name + "=" + aSubject.value + "\n");
- this.startLoginStatusTimer();
- }
- }
- }
- }
- else if ("timer-callback" == aTopic)
- {
- this.mLoginStatusTimer = null;
- var serverAuth = new AviaryServerAuth("gettoollist");
- }
- },
-
- // aviaryIAuth implementation.
- get isLoggedIn()
- {
- return this.mIsLoggedIn;
- },
-
- get toolsList()
- {
- return this.mToolsList;
- },
-
- Logout: function()
- {
- var serverAuth = new AviaryServerAuth("logout");
- },
-
- // internal functions.
- startLoginStatusTimer: function()
- {
- if (this.mLoginStatusTimer)
- this.mLoginStatusTimer.cancel();
- else
- {
- this.mLoginStatusTimer = Components.classes["@mozilla.org/timer;1"]
- .createInstance(Components.interfaces.nsITimer);
- }
-
- if (this.mLoginStatusTimer)
- {
- this.mLoginStatusTimer.init(this, this.kLoginStatusTimerInterval,
- this.mLoginStatusTimer.TYPE_ONE_SHOT);
- }
- },
-
- cancelLoginStatusTimer: function()
- {
- if (this.mLoginStatusTimer)
- {
- this.mLoginStatusTimer.cancel();
- this.mLoginStatusTimer = null;
- }
- },
-
- checkForToolsWindow: function(aWindow)
- {
- try
- {
- var win = aWindow.document.documentElement;
- if ("navigator:browser" == win.getAttribute("windowtype"))
- var tabListener = new AviaryTabListener(aWindow,
- this.mAviaryServerHost);
- } catch (e) {}
- },
-
- getHostFromURI: function(aURI)
- {
- try
- {
- return aURI.host; // This throws for URLs such as about:blank.
- } catch (e) {}
-
- return null;
- },
-
- endOfObject: true
- };
-
-
- // It would be better to nest this within gAviaryAuth.
- // aCommand can be one of: "logout", "isloggedin", "gettoollist"
- function AviaryServerAuth(aCommand)
- {
- this.init(aCommand)
- }
-
- AviaryServerAuth.prototype =
- {
- kServerURL: "",
- kServerURLSuffix: "/apps/xmlapi/login.aspx",
-
- mCommand: null,
- mRequest: null,
-
- init: function(aCommand)
- {
- if (!aCommand)
- {
- throw new Components.Exception("missing parameter",
- Components.results.NS_ERROR_INVALID_ARG);
- }
-
- try
- {
- var prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- var serverPrefix = prefSvc.getCharPref("aviary.serverPrefix");
- this.kServerURL = serverPrefix + this.kServerURLSuffix;
- } catch (e) {}
-
- this.mCommand = aCommand;
-
- // Create and initialize request.
- const kCI = Components.interfaces;
- const kXMLHttpRequestCID = "@mozilla.org/xmlextras/xmlhttprequest;1";
- this.mRequest = Components.classes[kXMLHttpRequestCID]
- .createInstance(kCI.nsIXMLHttpRequest);
-
- var self = this;
- this.mRequest.onload = function() { self.onLoad(self); }
- this.mRequest.onerror = function() { self.onError(self); }
-
- //dump(aCommand + " - AviaryServerAuth init about to call .open()\n");
- this.mRequest.open("POST", this.kServerURL, true);
- if (!gAviaryAuth.mPearlUtilRequest) try
- {
- // Load Pearl Utility Request library.
- var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
- .createInstance(Components.interfaces.mozIJSSubScriptLoader);
- loader.loadSubScript("chrome://aviary/content/pearlutil-request.js");
- gAviaryAuth.mPearlUtilRequest = com.aviary.talon.request;
- } catch (e) {}
-
- if (gAviaryAuth.mPearlUtilRequest)
- {
- gAviaryAuth.mPearlUtilRequest.
- EnsureCookiesWillBeSent(this.mRequest.channel, null);
- }
-
- this.mRequest.setRequestHeader("Content-type",
- "application/x-www-form-urlencoded");
- var formParams = "mode=" + encodeURIComponent(this.mCommand);
- // dump("auth request: " + formParams + "\n");
-
- this.mRequest.send(formParams);
- },
-
- onLoad: function(aThisObj)
- {
- var succeeded = false;
- try {
- const kHttpChannelCID = Components.interfaces.nsIHttpChannel;
- var channel = aThisObj.mRequest.channel.QueryInterface(kHttpChannelCID);
- succeeded = channel.requestSucceeded;
- } catch(e) { dump("onLoad: " + e + "\n"); }
-
- var responseText = aThisObj.mRequest.responseText;
- // dump(aThisObj.mCommand + " - auth response text:\n" + responseText + "\n\n\n");
- var obsSvc = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- if (succeeded && obsSvc)
- {
- var toolsList = gAviaryAuth.kDefaultToolsList;
-
- if ("isloggedin" == aThisObj.mCommand)
- {
- var isLoggedIn = ("true" == responseText);
- obsSvc.notifyObservers(null, "aviary:loginstatus", isLoggedIn);
- }
- else if ("gettoollist" == aThisObj.mCommand)
- {
- var isLoggedIn = (("failure" != responseText) &&
- (responseText.indexOf(',') > 0));
- obsSvc.notifyObservers(null, "aviary:loginstatus", isLoggedIn);
- if (isLoggedIn)
- toolsList = responseText;
- obsSvc.notifyObservers(null, "aviary:toolsavailable", toolsList);
- }
- else if ("logout" == aThisObj.mCommand)
- {
- obsSvc.notifyObservers(null, "aviary:loginstatus", false);
- obsSvc.notifyObservers(null, "aviary:toolsavailable", toolsList);
- }
- }
-
- if (!succeeded)
- {
- aThisObj.onError(aThisObj);
- return;
- }
- },
-
- onError: function(aThisObj)
- {
- var errMsg;
- // TODO: fit this error message within a caller-provider message.
- // TODO: report errors to user?
- if (!errMsg)
- errMsg = "Authentication failed."; // TODO: L10n
- // dump(aThisObj.mCommand + " - auth error: " + errMsg + "\n");
- },
-
- getBrowserWindow: function()
- {
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- return wm.getMostRecentWindow("navigator:browser");
- },
-
- endOfObject: true
- }
-
- function AviaryTabListener(aWindow, aServerHost)
- {
- this.init(aWindow, aServerHost);
- }
-
- AviaryTabListener.prototype =
- {
- kAviaryToolsSuffix1: "/flash/",
- kAviaryToolsSuffix2: "/apps/flash/",
- kAviaryToolsSuffix3: "/launch/",
- kCIWebProgress : Components.interfaces.nsIWebProgress,
-
- mWindow: null,
- mServerHost: null,
-
- init: function(aWindow, aServerHost)
- {
- if (aServerHost)
- this.mServerHost = aServerHost.toLowerCase();
-
- if (aWindow)
- {
- this.mWindow = aWindow.document.documentElement;
- var tabBrowser = aWindow.document.getElementById("content");
- tabBrowser.addProgressListener(this, this.kCIWebProgress.NOTIFY_LOCATION);
- }
- },
-
- // nsISupports:
- QueryInterface: function(aIID)
- {
- if (aIID.equals(Components.interfaces.nsIWebProgressListener)
- || aIID.equals(Components.interfaces.nsISupports)
- || aIID.equals(Components.interfaces.nsISupportsWeakReference))
- {
- return this;
- }
-
- throw Components.results.NS_NOINTERFACE;
- },
-
- // nsIWebProgressListener:
- onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {},
-
- onProgressChange: function(aWebProgress, aRequest,
- aCurrentSelfProgress, aMaxSelfProgress,
- aCurrentTotalProgress, aMaxTotalProgress) {},
-
- onLocationChange: function(aWebProgress, aRequest, aLocationURI)
- {
- if (aWebProgress && aLocationURI && this.mWindow)
- {
- var hideTBItem = false;
- var host = gAviaryAuth.getHostFromURI(aLocationURI);
- if (host && aLocationURI.path && (host.toLowerCase() == this.mServerHost))
- {
- var path = aLocationURI.path;
- hideTBItem = this.startsWith(path, this.kAviaryToolsSuffix1)
- || this.startsWith(path, this.kAviaryToolsSuffix2)
- || this.startsWith(path, this.kAviaryToolsSuffix3);
- }
-
- if (hideTBItem)
- this.mWindow.setAttribute("aviary-hide-tbitem", "true");
- else
- this.mWindow.removeAttribute("aviary-hide-tbitem");
- }
- },
-
- onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) {},
- onSecurityChange: function(aWebProgress, aRequest, aState) {},
-
- // Private functions.
- startsWith: function(aStr, aPrefix)
- {
- if (!aStr || !aPrefix)
- return false;
-
-
- var prefixLen = aPrefix.length;
- return ((aStr.length >= prefixLen)
- && (aPrefix == aStr.substr(0, prefixLen)));
- },
-
- endOfObject: true
- }
-
- var gAviaryAuthSvcModule =
- {
- kICompReg: Components.interfaces.nsIComponentRegistrar,
- kClassID: gAviaryAuth.kClassID,
- kContractID: gAviaryAuth.kContractID,
- kServiceName: gAviaryAuth.kServiceName,
-
- // nsISupports implementation.
- QueryInterface: function (aIID)
- {
- if (aIID.equals(Components.interfaces.nsIModule) ||
- aIID.equals(Components.interfaces.nsISupports))
- return this;
-
- throw Components.results.NS_ERROR_NO_INTERFACE;
- },
-
- // nsIModule implementation.
- getClassObject: function (aCompMgr, aClassID, aIID)
- {
- if (!aClassID.equals(this.kClassID))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- if (!aIID.equals(Components.interfaces.nsIFactory))
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
- return gAviaryAuth.QueryInterface(aIID);
- },
-
- registerSelf: function (aCompMgr, aFileSpec, aLocation, aType)
- {
- aCompMgr = aCompMgr.QueryInterface(this.kICompReg);
- aCompMgr.registerFactoryLocation(this.kClassID, this.kServiceName,
- this.kContractID, aFileSpec, aLocation, aType);
-
- var catMgr = Components.classes["@mozilla.org/categorymanager;1"]
- .getService(Components.interfaces.nsICategoryManager);
- catMgr.addCategoryEntry("app-startup", this.kServiceName, this.kContractID,
- true, true);
- },
-
- unregisterSelf: function (aCompMgr, aFileSpec, aLocation)
- {
- var catMgr = Components.classes["@mozilla.org/categorymanager;1"]
- .getService(Components.interfaces.nsICategoryManager);
- catMgr.deleteCategoryEntry("app-startup", this.kServiceName, true);
-
- aCompMgr = aCompMgr.QueryInterface(this.kICompReg);
- aCompMgr.unregisterFactoryLocation(this.kClassID, aFileSpec);
- },
-
- canUnload: function (aCompMgr) { return true; },
-
- endOfObject: true
- };
-
-
- function NSGetModule(aCompMgr, aFileSpec)
- {
- return gAviaryAuthSvcModule;
- }
-
-